package com.gitee.dolt.database.validator;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gitee.dolt.core.util.SpringUtils;
import com.gitee.dolt.database.util.MybatisUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.List;

/**
 * 唯一性约束逻辑判断
 *
 * @author LYH
 */
public class ColumnUniqueConstraintValidator implements ConstraintValidator<ColumnUnique, Object> {

    private IService superService;
    private String id;
    private String[] properties;
    private boolean supportUpdate;

    @Override
    public void initialize(ColumnUnique constraintAnnotation) {
        this.superService = SpringUtils.getBean(constraintAnnotation.service());
        this.id = constraintAnnotation.id();
        this.properties = StrUtil.split(constraintAnnotation.property(), StrUtil.COMMA);
        this.supportUpdate = constraintAnnotation.supportUpdate();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        boolean noValue = true;
        QueryWrapper<Object> qw = Wrappers.query();
        Class entityClass = superService.getEntityClass();
        for (int i = 0; i < properties.length; i++) {
            String property = properties[i];
            String column = MybatisUtils.getDbField(property, entityClass);
            Object propertyValue = BeanUtil.getProperty(value, property);
            if (propertyValue != null) {
                noValue = false;
                qw = qw.eq(column, propertyValue);
            } else {
                qw = qw.isNull(column);
            }
        }
        if (noValue) {
            return true;
        }
        List<Object> obs = superService.list(qw);
        if (obs.isEmpty()) {
            return true;
        }
        if (obs.size() > 1) {
            return false;
        }
        // 到此有且仅有一个
        Object idValue = BeanUtil.getProperty(value, this.id);
        if (idValue == null) {
            return false;
        }
        if (!this.supportUpdate || idValue.equals(MybatisUtils.getId(obs.get(0), superService.getEntityClass()))) {
            return true;
        }
        return false;
    }

}